/*****************************************************************************
 *   Copyright(C)2009-2019 by VSF Team                                       *
 *                                                                           *
 *  Licensed under the Apache License, Version 2.0 (the "License");          *
 *  you may not use this file except in compliance with the License.         *
 *  You may obtain a copy of the License at                                  *
 *                                                                           *
 *     http://www.apache.org/licenses/LICENSE-2.0                            *
 *                                                                           *
 *  Unless required by applicable law or agreed to in writing, software      *
 *  distributed under the License is distributed on an "AS IS" BASIS,        *
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
 *  See the License for the specific language governing permissions and      *
 *  limitations under the License.                                           *
 *                                                                           *
 ****************************************************************************/

#ifndef __USRAPP_COMMON_H__
#define __USRAPP_COMMON_H__

#if VSF_USE_USB_HOST_HCD_LIBUSB == ENABLED
#   include "component/usb/driver/hcd/libusb_hcd/vsf_libusb_hcd.h"
#elif VSF_USE_USB_HOST_HCD_WINUSB == ENABLED
#   include "component/usb/driver/hcd/winusb_hcd/vsf_winusb_hcd.h"
#endif

/*============================ INCLUDES ======================================*/
/*============================ MACROS ========================================*/
/*============================ MACROFIED FUNCTIONS ===========================*/
/*============================ TYPES =========================================*/

#if VSF_USE_USB_HOST == ENABLED
struct usrapp_common_const_t {
#   if VSF_USE_USB_HOST == ENABLED
    struct {
#       if VSF_USE_USB_HOST_HCD_OHCI == ENABLED
        vk_ohci_param_t ohci_param;
#       elif VSF_USE_USB_HOST_HCD_LIBUSB == ENABLED
        vsf_libusb_hcd_param_t libusb_hcd_param;
#       elif VSF_USE_USB_HOST_HCD_WINUSB == ENABLED
        vsf_winusb_hcd_param_t winusb_hcd_param;
#       endif
    } usbh;
#   endif
};
typedef struct usrapp_common_const_t usrapp_common_const_t;
#endif

#if VSF_USE_USB_HOST == ENABLED || VSF_USE_FS == ENABLED
struct usrapp_common_t {
#   if VSF_USE_USB_HOST == ENABLED
    struct {
        vk_usbh_t host;
#       if VSF_USE_USB_HOST_HUB == ENABLED
        vk_usbh_class_t hub;
#       endif
#       if VSF_USE_USB_HOST_LIBUSB == ENABLED
        vk_usbh_class_t libusb;
#       endif
#       if VSF_USE_TCPIP == ENABLED && VSF_USE_USB_HOST_ECM == ENABLED
        vk_usbh_class_t ecm;
#       endif
#       if VSF_USE_USB_HOST_BTHCI == ENABLED
        vk_usbh_class_t bthci;
#       endif
#       if VSF_USE_USB_HOST_HID == ENABLED
        vk_usbh_class_t hid;
#       endif
#       if VSF_USE_USB_HOST_DS4 == ENABLED
        vk_usbh_class_t ds4;
#       endif
#       if VSF_USE_USB_HOST_NSPRO == ENABLED
        vk_usbh_class_t nspro;
#       endif
#       if VSF_USE_USB_HOST_XB360 == ENABLED
        vk_usbh_class_t xb360;
#       endif
#       if VSF_USE_USB_HOST_XB1 == ENABLED
        vk_usbh_class_t xb1;
#       endif
    } usbh;
#   endif

#   if VSF_USE_FS == ENABLED
    struct {
#       if VSF_USE_MEMFS == ENABLED
        vk_memfs_info_t memfs_info;
#       endif
#       if VSF_USE_WINFS == ENABLED
        vk_winfs_info_t winfs_info;
#       endif
    } fs;
#   endif
};
typedef struct usrapp_common_t usrapp_common_t;
#endif

/*============================ GLOBAL VARIABLES ==============================*/

#if VSF_USE_USB_HOST == ENABLED
static const usrapp_common_const_t __usrapp_common_const = {
#   if VSF_USE_USB_HOST == ENABLED
    .usbh                   = {
#       if VSF_USE_USB_HOST_HCD_OHCI == ENABLED
        .ohci_param         = {
            .op             = &VSF_USB_HC0_IP,
            .priority       = vsf_arch_prio_0,
        },
#       elif VSF_USE_USB_HOST_HCD_LIBUSB == ENABLED
        .libusb_hcd_param = {
            .priority = vsf_arch_prio_0,
        },
#       elif VSF_USE_USB_HOST_HCD_WINUSB == ENABLED
        .winusb_hcd_param = {
            .priority = vsf_arch_prio_0,
        },
#       endif
    },
#   endif
};
#endif

#if VSF_USE_USB_HOST == ENABLED || VSF_USE_FS == ENABLED
static usrapp_common_t __usrapp_common = {
#   if VSF_USE_USB_HOST == ENABLED
    .usbh                   = {
#       if VSF_USE_USB_HOST_HCD_OHCI == ENABLED
        .host.drv           = &vk_ohci_drv,
        .host.param         = (void *)&__usrapp_common_const.usbh.ohci_param,
#       elif VSF_USE_USB_HOST_HCD_LIBUSB == ENABLED
        .host.drv           = &vsf_libusb_hcd_drv,
        .host.param         = (void*)&__usrapp_common_const.usbh.libusb_hcd_param,
#       elif VSF_USE_USB_HOST_HCD_WINUSB == ENABLED
        .host.drv           = &vsf_winusb_hcd_drv,
        .host.param         = (void*)&__usrapp_common_const.usbh.winusb_hcd_param,
#       endif

#       if VSF_USE_USB_HOST_HUB == ENABLED
        .hub.drv            = &vk_usbh_hub_drv,
#       endif
#       if VSF_USE_TCPIP == ENABLED && VSF_USE_USB_HOST_ECM == ENABLED
        .ecm.drv            = &vk_usbh_ecm_drv,
#       endif
#       if VSF_USE_USB_HOST_LIBUSB == ENABLED
        .libusb.drv         = &vk_usbh_libusb_drv,
#       endif
#       if VSF_USE_USB_HOST_BTHCI == ENABLED
        .bthci.drv          = &vk_usbh_bthci_drv,
#       endif
#       if VSF_USE_USB_HOST_HID == ENABLED
        .hid.drv            = &vk_usbh_hid_drv,
#       endif
#       if VSF_USE_USB_HOST_DS4 == ENABLED
        .ds4.drv            = &vk_usbh_ds4_drv,
#       endif
#       if VSF_USE_USB_HOST_NSPRO == ENABLED
        .nspro.drv          = &vk_usbh_nspro_drv,
#       endif
#       if VSF_USE_USB_HOST_XB360 == ENABLED
        .xb360.drv          = &vk_usbh_xb360_drv,
#       endif
#       if VSF_USE_USB_HOST_XB1 == ENABLED
        .xb1.drv            = &vk_usbh_xb1_drv,
#       endif
    },
#   endif

#   if VSF_USE_FS == ENABLED
    .fs                         = {
#       if VSF_USE_MEMFS == ENABLED
        .memfs_info             = {
            .root               = {
                .d.child        = (vk_memfs_file_t *)USRAPP_CFG_MEMFS_ROOT,
                .d.child_num    = dimof(USRAPP_CFG_MEMFS_ROOT),
                .d.child_size   = sizeof(vk_fakefat32_file_t),
            },
        },
#       endif
#       if VSF_USE_WINFS == ENABLED
        .winfs_info             = {
            .root               = {
                .name           = USRAPP_CFG_WINFS_ROOT,
            },
        },
#       endif
    },
#   endif
};
#endif

/*============================ LOCAL VARIABLES ===============================*/
/*============================ PROTOTYPES ====================================*/
/*============================ IMPLEMENTATION ================================*/

static inline vsf_err_t __usrapp_common_init(void)
{
#if VSF_USE_TRACE == ENABLED
    vsf_trace_init(NULL);
#   if USRAPP_CFG_STDIO_EN == ENABLED
    vsf_stdio_init();
#   endif
#endif

#if VSF_USE_USB_HOST == ENABLED
#   if VSF_USE_USB_HOST_HCD_OHCI == ENABLED
    vk_ohci_init();
#   endif
    vk_usbh_init(&__usrapp_common.usbh.host);
#   if VSF_USE_USB_HOST_LIBUSB == ENABLED
    vk_usbh_register_class(&__usrapp_common.usbh.host, &__usrapp_common.usbh.libusb);
#   endif
#   if VSF_USE_TCPIP == ENABLED && VSF_USE_USB_HOST_ECM == ENABLED
    vk_usbh_register_class(&__usrapp_common.usbh.host, &__usrapp_common.usbh.ecm);
#   endif
#   if VSF_USE_USB_HOST_BTHCI == ENABLED
    vk_usbh_register_class(&__usrapp_common.usbh.host, &__usrapp_common.usbh.bthci);
#   endif
#   if VSF_USE_USB_HOST_HID == ENABLED
    vk_usbh_register_class(&__usrapp_common.usbh.host, &__usrapp_common.usbh.hid);
#   endif
#   if VSF_USE_USB_HOST_DS4 == ENABLED
    vk_usbh_register_class(&__usrapp_common.usbh.host, &__usrapp_common.usbh.ds4);
#   endif
#   if VSF_USE_USB_HOST_NSPRO == ENABLED
    vk_usbh_register_class(&__usrapp_common.usbh.host, &__usrapp_common.usbh.nspro);
#   endif
#   if VSF_USE_USB_HOST_XB360 == ENABLED
    vk_usbh_register_class(&__usrapp_common.usbh.host, &__usrapp_common.usbh.xb360);
#   endif
#   if VSF_USE_USB_HOST_XB1 == ENABLED
    vk_usbh_register_class(&__usrapp_common.usbh.host, &__usrapp_common.usbh.xb1);
#   endif
#   if VSF_USE_USB_HOST_HUB == ENABLED
    vk_usbh_register_class(&__usrapp_common.usbh.host, &__usrapp_common.usbh.hub);
#   endif
#endif

    return VSF_ERR_NONE;
}

#endif      // __USRAPP_COMMON_H__
/* EOF */